from ..base import base
from flask import Flask, request, Response, jsonify
import os
from http import HTTPStatus
from dashscope import Application
from werkzeug.utils import secure_filename
import PyPDF2
import docx
import openpyxl
from  .analysis import StandardInspect
import logging
from .analysis import DocumentInspection  # 在顶部导入
import json


logger = logging.getLogger(__name__)
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['ALLOWED_EXTENSIONS'] = {'doc', 'docx', 'pdf','xlsx'}
app.session_id = None

def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']


def process_pdf(filepath):
    """处理PDF文件"""
    with open(filepath, 'rb') as file:
        reader = PyPDF2.PdfReader(file)
        return "\n".join([page.extract_text() for page in reader.pages])


def process_word(filepath, promptStr):
    """处理Word文档"""
    doc_content = DocumentInspection.read_docx_tables(filepath)
    content = json.dumps(doc_content, ensure_ascii=False, indent=2)
    problem_count = 0
    if isinstance(doc_content, dict) and 'sections' in doc_content:
        problem_count = sum(len(section.get('tables', [])) for section in doc_content['sections'])
    return f"文档内容：{content}\n\n核查问题（共发现{problem_count}个问题）\n\n用户问题：{promptStr}", problem_count


def process_excel(filepath, promptStr=""):
    """处理Excel文件并返回HeCha数据（只进行数据模型检查）"""
    try:
        # 修改为直接调用验证函数
        from .analysis.ShuJuHeCha import validate_excel_physical_model

        # 只进行数据模型验证
        return validate_excel_physical_model([filepath])

    except Exception as e:
        logger.error(f"Excel文件处理异常: {str(e)}")
        raise
# @app.route('/')
# def index():
#     return render_template('index.html')

@base.route('/smart/qa/chat', methods=['post'])
def chat():
    promptStr = request.json.get('message')
    filename = request.json.get("filename")
    if filename:
        upload_dir = app.config['UPLOAD_FOLDER']
        filepath = os.path.join(upload_dir, filename)
        promptStr = f"分析文档内容：{filepath}"

    response = Application.call(
        api_key='sk-00d9f8f5b8084c90b30654f6f2ee0a32',
        app_id='fa8dfc29ca064046ba9709048aa9f6d4',
        prompt=promptStr,
        session_id=app.session_id)
    
    if response.status_code == HTTPStatus.OK:
        app.session_id = response.output.session_id
        return {'reply': response.output.text}
    else:
        return {'error': f"请求失败：{response.message} (代码：{response.status_code})"}, 500

def event_stream(responses):
    for response in responses:
        if response.status_code != HTTPStatus.OK:
            yield f"data: {response}\n\n"  # SSE格式要求
        else:
            yield f"data: {response}\n\n"  # SSE格式要求

@base.route('/smart/qa/chatstream', methods=['GET'])
def qa_chatStream():
    header_str = ""
    inspect_errors = ""
    hecha_data = ""
    promptStr = request.args.get('message')
    filename = request.args.get("filename")
    promptContent = promptStr
    if filename:
        upload_dir = app.config['UPLOAD_FOLDER']
        filepath = os.path.join(upload_dir, filename)

        # 存储核查数据
        # hecha_storage = {}
        # 检查文件是否存在
        if not os.path.exists(filepath):
            return jsonify({'error': '文件不存在'}), 404

        problem_count = 0
        try:
            # 读取文件内容
            if filename.endswith('.pdf'):
                with open(filepath, 'rb') as file:
                    reader = PyPDF2.PdfReader(file)
                    content = "\n".join([page.extract_text() for page in reader.pages])
            elif filename.endswith(('.doc', '.docx')):
                try:
                    doc_content = DocumentInspection.read_docx_tables(filepath)
                    content = json.dumps(doc_content, ensure_ascii=False)
                    logger.debug(f"Docx解析结果长度: {len(content)} 字符")
                    inspect_errors = content
                except Exception as e:
                    logger.error(f"Docx解析失败: {str(e)}", exc_info=True)  # 记录完整异常栈
                    return {'error': f'文档解析失败：{str(e)}'}, 500
            elif filepath.endswith('.xlsx'):
                if filename.startswith('基线表'):
                    problem_count, hecha_data = process_excel(filepath, promptStr)
                else:
                   # 解析Excel文件
                   wb = openpyxl.load_workbook(filepath)
                   text = []
                   headers = []
                   for sheet in wb:
                      #提取表头
                      try:
                          first_row = next(sheet.iter_rows(values_only=True))
                          headers.extend([str(h) for h in first_row if h is not None and h != ''])
                          #提取所有行数据
                          for row in sheet.iter_rows(values_only=True):
                               text.append('\t'.join(map(str, row)))
                      except Exception as e:
                          pass
                   content = '\n'.join(text)
                   # 拼接表头为逗号分隔字符串
                   header_str = ','.join(headers)
                   inspect_errors = StandardInspect.read_excel_file(filepath)
                   # 最终优化统计逻辑
                   problem_count = 0
                   if inspect_errors:
                       import re
                       # 匹配带括号或花括号的条目结构
                       pattern = re.compile(r'([({].*?[})])')

                       if isinstance(inspect_errors, str):
                           # 提取所有有效条目
                           entries = pattern.findall(inspect_errors)
                           # 过滤空条目并去重
                           entries = list(set([e.strip(" (){}") for e in entries if e]))
                           problem_count = len(entries)
                           # 增强调试日志
                           logger.debug(f"精确条目统计 - 总数:{problem_count} 有效条目:{entries}")
                       elif isinstance(inspect_errors, list):
                           problem_count = len(inspect_errors)
                       elif isinstance(inspect_errors, dict):
                           problem_count = len(inspect_errors.get('errors', []))
            else:  # .doc or other text files
                with open(filepath, 'r', encoding='utf-8') as file:
                    content = file.read()

            if hecha_data:
                promptContent = f"核查问题：{hecha_data}（共发现{problem_count}个问题）\n\n 用户咨询问题：{promptStr} ,输出格式要清晰明了，多次输出且格式保持不变"

            elif header_str:
                promptContent = f"表头内容：{header_str}\n\n核查问题（共发现{problem_count}个问题）:{inspect_errors}\n\n用户咨询问题：{promptStr}"
            else:
                # 修正变量引用错误
                promptContent = f"核查问题（共发现{problem_count}个问题）:{inspect_errors}\n\n用户咨询问题：{promptStr}"
        except Exception as e:
            return {'error': f'文件读取失败：{str(e)}'}, 500
    # 保持原有日志记录方式
    logger.error("promptContent:"+promptContent+"\n\n")  # 原有日志代码不变
    # 新增Word文档解析日志
    if filename and filename.endswith(('.doc', '.docx')):
        logger.info(f"Word文档解析完成，共发现{problem_count}个待核查问题")
    # 修改为增量流式输出
    responses = Application.call(
        api_key='sk-00d9f8f5b8084c90b30654f6f2ee0a32',
        app_id='fa8dfc29ca064046ba9709048aa9f6d4',
        prompt= promptContent,
        session_id=app.session_id,
        # has_thoughts=True,
        stream=True,  # 启用流式输出
        incremental_output=True)  # 启用增量输出

    return Response(
        event_stream(responses),
        mimetype='text/event-stream'
    )

@base.route('/smart/qa/upload', methods=['POST'])
def upload_file():
    if 'file' not in request.files:
        return {'error': '未选择文件'}, 400
    
    file = request.files['file']
    if file.filename == '':
        return {'error': '未选择文件'}, 400
    
    if file and allowed_file(file.filename):
        filename = file.filename.strip()
        # 添加文件名有效性检查
        if not filename or '.' not in filename:
            return {'error': '无效的文件名'}, 400
            
        # 确保上传目录存在
        upload_dir = app.config['UPLOAD_FOLDER']
        os.makedirs(upload_dir, exist_ok=True)  # 新增目录创建
        
        filepath = os.path.join(upload_dir, filename)
        try:
            file.save(filepath)
        except Exception as e:
            return {'error': f'文件保存失败：{str(e)}'}, 500

        return {'status': 'success', 'filename': filename}
        # 调用百炼API分析文档
    #     response = Application.call(
    #         api_key='sk-00d9f8f5b8084c90b30654f6f2ee0a32',
    #         app_id='fa8dfc29ca064046ba9709048aa9f6d4',
    #         prompt=f"分析文档内容：{filepath}",
    #         session_id=app.session_id)
    #
    #     if response.status_code == HTTPStatus.OK:
    #         return {'status': 'success', 'analysis': response.output.text}
    #     else:
    #         return {'error': f"文档分析失败：{response.message}"}, 500
    # else:
    #     return {'error': '文件类型不支持'}, 400

if __name__ == '__main__':
    app.run(debug=True, port=5000)